package com.mazaiting.gateway.sentinel.runner;

import com.alibaba.cloud.sentinel.SentinelProperties;
import com.alibaba.cloud.sentinel.datasource.RuleType;
import com.alibaba.cloud.sentinel.datasource.config.DataSourcePropertiesConfiguration;
import com.alibaba.cloud.sentinel.datasource.config.NacosDataSourceProperties;
import com.alibaba.csp.sentinel.adapter.gateway.common.api.ApiDefinition;
import com.alibaba.csp.sentinel.adapter.gateway.common.command.UpdateGatewayApiDefinitionGroupCommandHandler;
import com.alibaba.csp.sentinel.adapter.gateway.common.command.UpdateGatewayRuleCommandHandler;
import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayFlowRule;
import com.alibaba.csp.sentinel.datasource.WritableDataSource;
import com.alibaba.fastjson.JSON;
import com.mazaiting.gateway.sentinel.write.NacosWritableDataSource;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * 数据源初始化
 *
 * @author mazaiting
 * @create_time 2022/10/14 11:16
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class DataSourceInitRunner implements ApplicationRunner {

    private final SentinelProperties sentinelProperties;

    @Override
    public void run(ApplicationArguments args) {
        if (Objects.isNull(sentinelProperties) || CollectionUtils.isEmpty(sentinelProperties.getDatasource())) {
            log.error("sentinel 配置为空");
            return;
        }
        // 获取数据源配置
        Map<String, DataSourcePropertiesConfiguration> datasourceMap = sentinelProperties.getDatasource();
        datasourceMap.forEach((s, configuration) -> {
            NacosDataSourceProperties nacos = configuration.getNacos();
            if (Objects.isNull(nacos)) {
                log.error("nacos 配置为空.");
                return;
            }
            // 规则类型
            RuleType ruleType = nacos.getRuleType();
            switch (ruleType) {
                case GW_FLOW -> {
                    WritableDataSource<Set<GatewayFlowRule>> gatewayFlowRuleList = new NacosWritableDataSource<>(nacos, data -> JSON.toJSONString(data, true));
                    UpdateGatewayRuleCommandHandler.setWritableDataSource(gatewayFlowRuleList);
                }
                case GW_API_GROUP -> {
                    WritableDataSource<Set<ApiDefinition>> apiDefinitionList = new NacosWritableDataSource<>(nacos, data -> JSON.toJSONString(data, true));
                    UpdateGatewayApiDefinitionGroupCommandHandler.setWritableDataSource(apiDefinitionList);
                }
                default -> log.error("未知规则类型: {}", ruleType);
            }
        });
    }

}
